/**
 *                            License
 * THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS  
 * CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). 
 * THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW.  
 * ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR  
 * COPYRIGHT LAW IS PROHIBITED.
 * 
 * BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND  
 * AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE  
 * MAY BE CONSIDERED TO BE A CONTRACT,
 * THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED 
 * HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
 * 
 */
package com.lineage.server.utils;

import static com.lineage.server.model.skill.L1SkillId.EARTH_BIND;
import static com.lineage.server.model.skill.L1SkillId.FOG_OF_SLEEPING;
import static com.lineage.server.model.skill.L1SkillId.FREEZING_BLIZZARD;
import static com.lineage.server.model.skill.L1SkillId.FREEZING_BREATH;
import static com.lineage.server.model.skill.L1SkillId.ICE_LANCE;
import static com.lineage.server.model.skill.L1SkillId.ICE_LANCE_BASILISK;
import static com.lineage.server.model.skill.L1SkillId.ICE_LANCE_COCKATRICE;
import static com.lineage.server.model.skill.L1SkillId.SHOCK_SKIN;
import static com.lineage.server.model.skill.L1SkillId.SHOCK_STUN;
import static com.lineage.server.model.skill.L1SkillId.STATUS_CURSE_PARALYZED;

import java.util.Collection;

import com.gui.manager.ServerManager;
import com.lineage.server.PacketCreate;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.L1World;
import com.lineage.server.model.Instance.L1DollInstance;
import com.lineage.server.model.Instance.L1ItemInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.identity.L1ItemId;

/**
 * Class <code>CheckUtil</code> 检查控制器.
 * 
 * @author jrwz
 * @version 2012-5-11下午02:21:03
 * @see com.lineage.server.utils
 * @since JDK1.7
 */
public final class CheckUtil {
    /** 金币最高数量. */
    private static final int MAX_COUNT_ADENA = 2000000000; // 20亿
    /** 道具最高数量(可堆叠). */
    private static final int MAX_COUNT_ITEM = 100000; // 10万

    /**
     * 检查该坐标位置是否能通过(是否有物件阻挡).
     * 
     * @param pc
     *            要检查的对象
     * @param locx
     *            坐标：X
     * @param locy
     *            坐标：Y
     * @param mapid
     *            地图编号
     * @return true有、false沒有
     */
    public static boolean checkIsPassable(final L1PcInstance pc,
            final int locx, final int locy, final int mapid) {

        // 5格范围内
        final Collection<L1Object> objAll = L1World.getInstance()
                .getVisibleObjects(pc, 5);
        for (final L1Object obj : objAll) {
            final L1Character character = (L1Character) obj;
            if (character instanceof L1NpcInstance) {
                final L1NpcInstance npc = (L1NpcInstance) character;
                if (npc instanceof L1DollInstance) { // 魔法娃娃
                    continue;
                }
                if ((npc.getX() == locx) && (npc.getY() == locy)
                        && (npc.getMapId() == mapid)) {
                    return true;
                }
            } else if (character instanceof L1PcInstance) {
                final L1PcInstance tgpc = (L1PcInstance) character;
                if ((tgpc.getX() == locx) && (tgpc.getY() == locy)
                        && (tgpc.getMapId() == mapid)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 是否为什么都不能做的状态 (无法离线、无法移动、无法使用道具等).
     * 
     * @param pc
     *            - 对象
     * 
     * @return true:是、false:否
     */
    public static boolean isCanNotDoAnything(final L1PcInstance pc) {
        return (/*
                 * pc.hasSkillEffect(IMMUNE_TO_HARM) // 法师魔法 (圣结界) 测试用 ||
                 */
        pc.hasSkillEffect(STATUS_CURSE_PARALYZED) // 麻痹毒(木乃伊诅咒)后
                || pc.hasSkillEffect(ICE_LANCE) // 法师魔法 (冰矛围篱)
                || pc.hasSkillEffect(FREEZING_BLIZZARD) // 法师魔法 (冰雪飓风)
                || pc.hasSkillEffect(ICE_LANCE_COCKATRICE) // 亚力安冰矛围篱
                || pc.hasSkillEffect(ICE_LANCE_BASILISK) // 邪恶蜥蜴冰矛围篱
                || pc.hasSkillEffect(FOG_OF_SLEEPING) // 法师魔法 (沉睡之雾)
                || pc.hasSkillEffect(SHOCK_STUN) // 骑士魔法 (冲击之晕)
                || pc.hasSkillEffect(EARTH_BIND) // 妖精魔法 (大地屏障)
                || pc.hasSkillEffect(SHOCK_SKIN) // 龙骑士魔法 (冲击之肤) 冲晕效果
        || pc.hasSkillEffect(FREEZING_BREATH)); // 龙骑士魔法 (寒冰喷吐)
    }

    /**
     * 检查道具是否异常(作弊),有异常就删除.
     * 
     * @param pc
     *            - 对象
     * @param item
     *            - 道具
     * @return 异常 true、正常 false
     */
    public static boolean itemCheck(final L1PcInstance pc,
            final L1ItemInstance item) {
        final int itemId = item.getItem().getItemId();
        final int itemCount = item.getCount();
        boolean isCheat = false;
        final int type = item.getItem().getType2();
        final boolean isStackable = item.getItem().isStackable();
        if (((type == 1) || (type == 2)) && (itemCount != 1)) {
            isCheat = true;
        } else if (type == 0) {
            // 不可堆叠的道具却堆叠，就视为作弊
            if (!isStackable && (itemCount != 1)) {
                isCheat = true;
                // 金币大于20亿以及金币负值则为作弊
            } else if ((itemId == L1ItemId.ADENA)
                    && ((itemCount > MAX_COUNT_ADENA) || (itemCount < 0))) {
                isCheat = true;
                // 可堆叠道具(金币除外)堆叠超过十万个以及堆叠负值则为作弊
            } else if (isStackable && (itemId != L1ItemId.ADENA)
                    && ((itemCount > MAX_COUNT_ITEM) || (itemCount < 0))) {
                isCheat = true;
            }
        }
        if (isCheat) {
            // 作弊直接删除物品
            pc.getInventory().removeItem(item, itemCount);
            PacketCreate.get().sendSinglePackets(pc, "道具异常");
            final String itemName = item.getItem().getName();
            ServerManager.上方框内的文字.append("\r\n[讯息] 玩家 " + pc.getName()
                    + " 的道具 " + itemName + " 已被删除(数量或堆叠异常)" + " 道具数量 "
                    + itemCount);
        }
        return isCheat;
    }

    /** 检查控制器. */
    private CheckUtil() {
    }
}
